package kubayaxi.video.client.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import kubayaxi.video.client.service.ICommentService;
import kubayaxi.video.mybatis.auto.dao.*;
import kubayaxi.video.mybatis.auto.model.*;
import kubayaxi.video.mybatis.customize.model.comment.dto.AddCommentDTO;
import kubayaxi.video.mybatis.customize.model.comment.dto.AllCommentDTO;
import kubayaxi.video.mybatis.customize.model.comment.dto.LikeCommentDTO;
import kubayaxi.video.mybatis.customize.model.comment.dto.QueryReplyDTO;
import kubayaxi.video.mybatis.customize.model.comment.vo.AllCommentVO;
import kubayaxi.video.mybatis.customize.model.comment.vo.CommentItem;
import kubayaxi.video.mybatis.customize.model.comment.vo.QueryReplyVO;
import kubayaxi.video.service.base.common.enums.DeleteEnum;
import kubayaxi.video.service.base.common.request.BaseRequest;
import kubayaxi.video.service.base.common.treadlocal.UserContent;
import kubayaxi.video.service.base.util.common.Asserts;
import kubayaxi.video.service.base.util.transaction.TransactionUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class CommentServiceImpl implements ICommentService {

    @Resource
    private CommentMapper commentMapper;
    @Resource
    private ConfMapper confMapper;
    @Resource
    private ClientUserMapper clientUserMapper;
    @Resource
    private TransactionUtil transactionUtil;
    @Resource
    private VideoMapper videoMapper;
    @Resource
    private LikeCommentRecordMapper likeCommentRecordMapper;

    /**
     * 全部评论
     */
    @Override
    public AllCommentVO allComment(BaseRequest<AllCommentDTO> dto) {
        AllCommentDTO data = dto.getData();
        Asserts.isNotNull(data.getVId(),"视频id为空");
        Long uId = UserContent.get();
        //找到视频的全部评论
        List<Comment> comments = commentMapper.selectList(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getVId, data.getVId())
                .eq(Comment::getDeleteStatus, DeleteEnum.NOT_DELETED.getCode())
                .isNull(Comment::getPId)
                .orderByDesc(Comment::getCreatedTime));
        List<CommentItem> wonderful = new ArrayList<>();
        List<CommentItem> latest = new ArrayList<>();
        //去配置表获取多少赞被称为精彩评论
        String likeCountSpeKey = "like_count_spe";
        Conf conf = confMapper.selectOne(new LambdaQueryWrapper<Conf>().eq(Conf::getKey, likeCountSpeKey));
        int likeCountSpe = Integer.parseInt(conf.getValue());
        //将精彩评论和最新评论分开
        comments.forEach(item -> {
            LikeCommentRecord likeCommentRecord = likeCommentRecordMapper.selectOne(new LambdaQueryWrapper<LikeCommentRecord>()
                    .eq(LikeCommentRecord::getCommentId, item.getId())
                    .eq(LikeCommentRecord::getUId, uId)
                    .eq(LikeCommentRecord::getDeleteStatus, DeleteEnum.NOT_DELETED.getCode()));
            CommentItem commentItem = CommentItem.builder()
                    .commentId(item.getId())
                    .portraitUrl(item.getPortraitUrl())
                    .nickName(item.getNickName())
                    .createdTime(item.getCreatedTime())
                    .likeNum(item.getLikeNum())
                    .content(item.getContent())
                    .commentNum(item.getCommentNum())
                    .haveReply(true)
                    .likeStatus(ObjectUtil.isNotNull(likeCommentRecord) ? 60:61)
                    .build();
            if (item.getLikeNum() >= likeCountSpe) {
                wonderful.add(commentItem);
            } else {
                latest.add(commentItem);
            }
        });
        //将精彩评论根据点赞数降序排序
        wonderful.sort((o1, o2) -> o2.getLikeNum() - o1.getLikeNum());
        AllCommentVO ans = new AllCommentVO();
        ans.setWonderful(wonderful);
        ans.setLatest(latest);
        return ans;
    }

    /**
     * 发布评论
     */
    @Override
    public void addComment(BaseRequest<AddCommentDTO> dto) {
        AddCommentDTO data = dto.getData();
        Asserts.isNotNull(data.getVId(),"视频id为空");
        Asserts.isNotBlank(data.getContent(),"内容为空");
        Long userId = UserContent.get();
        Comment comment = new Comment();
        comment.setContent(data.getContent());
        comment.setVId(data.getVId());
        comment.setPId(data.getPId());
        comment.setUId(userId);
        ClientUser clientUser = clientUserMapper.selectById(userId);
        comment.setPortraitUrl(clientUser.getPortraitUrl());
        comment.setNickName(clientUser.getNickName());
        boolean b = transactionUtil.transactional(() -> {
            //添加评论记录,修改回复评论数,修改视频评论数,事务操作
            int insert = commentMapper.insert(comment);
            int update1 = 1;
            if (ObjectUtil.isNotNull(data.getPId())) {
                update1 = commentMapper.update(null, new LambdaUpdateWrapper<Comment>()
                        .eq(Comment::getId, data.getPId())
                        .setSql("comment_num = comment_num + 1"));
            }
            int update2 = videoMapper.update(null, new LambdaUpdateWrapper<Video>()
                    .eq(Video::getId, data.getVId())
                    .setSql("comment_num = comment_num + 1"));
            return insert == 1 && update1 == 1 && update2 == 1;
        });
        Asserts.isTrue(b,"添加评论失败");
    }

    /**
     * 点赞评论
     */
    @Override
    public void likeComment(BaseRequest<LikeCommentDTO> dto) {
        LikeCommentDTO data = dto.getData();
        Asserts.isNotNull(data.getVId(),"视频id为空");
        Asserts.isNotNull(data.getPId(),"评论父id为空");
        Long uId = UserContent.get();
        LikeCommentRecord record = likeCommentRecordMapper.selectOne(new LambdaQueryWrapper<LikeCommentRecord>()
                .eq(LikeCommentRecord::getCommentId, data.getPId())
                .eq(LikeCommentRecord::getUId, uId));
        Asserts.isNull(record,"已点赞评论");
        boolean b = transactionUtil.transactional(() -> {
            //添加喜欢评论记录,修改评论喜欢数
            LikeCommentRecord likeCommentRecord = new LikeCommentRecord();
            likeCommentRecord.setCommentId(data.getPId());
            likeCommentRecord.setUId(uId);
            int insert = likeCommentRecordMapper.insert(likeCommentRecord);
            int update = commentMapper.update(null, new LambdaUpdateWrapper<Comment>()
                    .eq(Comment::getId, data.getPId())
                    .setSql("like_num = like_num + 1"));
            return insert == 1 && update == 1;
        });
        Asserts.isTrue(b,"点赞失败");
    }

    /**
     * 回复评论
     */
    @Override
    public QueryReplyVO queryReply(BaseRequest<QueryReplyDTO> dto) {
        QueryReplyDTO data = dto.getData();
        Asserts.isNotNull(data.getCommentId(),"评论id为空");
        Long uId = UserContent.get();
        List<Comment> comments = commentMapper.selectList(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getPId, data.getCommentId())
                .eq(Comment::getDeleteStatus, DeleteEnum.NOT_DELETED.getCode())
                .orderByDesc(Comment::getCreatedTime));
        List<CommentItem> list = new ArrayList<>();
        for (Comment item : comments) {
            LikeCommentRecord likeCommentRecord = likeCommentRecordMapper.selectOne(new LambdaQueryWrapper<LikeCommentRecord>()
                    .eq(LikeCommentRecord::getCommentId, item.getId())
                    .eq(LikeCommentRecord::getUId, uId));
            CommentItem commentItem = CommentItem.builder()
                    .commentId(item.getId())
                    .portraitUrl(item.getPortraitUrl())
                    .nickName(item.getNickName())
                    .createdTime(item.getCreatedTime())
                    .likeNum(item.getLikeNum())
                    .content(item.getContent())
                    .commentNum(item.getCommentNum())
                    .likeStatus(ObjectUtil.isNotNull(likeCommentRecord) ? 60:61)
                    .build();
            list.add(commentItem);
        }
        QueryReplyVO ans = new QueryReplyVO();
        ans.setComments(list);
        return ans;
    }
}
